package cn.wen.yinxiu.member.service.impl;

import cn.wen.yinxiu.common.convention.result.ResultEntity;
import cn.wen.yinxiu.common.enums.DelEnum;
import cn.wen.yinxiu.common.enums.StatusEnum;
import cn.wen.yinxiu.common.enums.UserEnum;
import cn.wen.yinxiu.common.to.system.NoticeTO;
import cn.wen.yinxiu.common.to.user.UserLoginTO;
import cn.wen.yinxiu.common.to.user.UserSimpleTO;
import cn.wen.yinxiu.common.to.user.UserTO;
import cn.wen.yinxiu.common.to.works.SimpleWorksTO;
import cn.wen.yinxiu.member.builder.BeanBuilderAssistant;
import cn.wen.yinxiu.member.entity.*;
import cn.wen.yinxiu.member.feign.SystemFeignService;
import cn.wen.yinxiu.member.feign.WorksFeignService;
import cn.wen.yinxiu.member.service.*;
import cn.wen.yinxiu.common.to.user.UserDataInfo;
import cn.wen.yinxiu.member.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.wen.yinxiu.common.toolkit.PageUtils;
import cn.wen.yinxiu.common.toolkit.Query;

import cn.wen.yinxiu.member.dao.UsersDao;

import static cn.wen.yinxiu.common.constant.Constant.TalkType.Friend;
import static cn.wen.yinxiu.common.constant.Constant.TalkType.Group;

@Slf4j
@Service("usersService")
public class UsersServiceImpl extends ServiceImpl<UsersDao, UsersEntity> implements UsersService {

    @Value("${yinxiu.pageSize}")
    private Integer pageSize;

    @Autowired
    private UsersDao usersDao;

    @Autowired
    private TalkBoxService talkBoxService;

    @Autowired
    private GroupService groupService;

    @Autowired
    private FriendService friendService;

    @Autowired
    private ChatRecordService chatRecordService;

    @Autowired
    private WorksFeignService worksFeignService;

    @Autowired
    private SystemFeignService systemFeignService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<UsersEntity> page = this.page(
                new Query<UsersEntity>().getPage(params),
                new QueryWrapper<UsersEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public boolean checkAuth(String account, String userPassword) {
        // 1.判断是否存在当前用户
        QueryWrapper<UsersEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("account", account);
        queryWrapper.eq("status", StatusEnum.NORMAL_USE.code());
        queryWrapper.eq("is_deleted", DelEnum.NORMAL.code());
        UsersEntity user = usersDao.selectOne(queryWrapper);
        if (user == null) return false;
        // 比对密码
        boolean isCheck = user.getPassword().equals(userPassword);
        return isCheck;
    }

    @Override
    public UserInfoVO queryUserInfoById(Long userId) {
        // TODO 需要先校验是否是本人
        UsersEntity usersEntity = usersDao.selectById(userId);
        return BeanBuilderAssistant.userEntToUserInfoVO(usersEntity);
    }

    @Override
    public UserInfo queryUserInfo(Long userId) {
        UsersEntity user = usersDao.selectById(userId);
        return BeanBuilderAssistant.userEntToUserInfo(user);
    }

    @Override
    public List<TalkBoxInfo> queryTalkBoxInfoList(Long userId) {
        List<TalkBoxInfo> talkBoxInfoList = new ArrayList<>();
        List<TalkBoxEntity> talkBoxList = talkBoxService.queryTalkBoxInfoListByUserId(userId);
        for (TalkBoxEntity talkBox : talkBoxList) {
            TalkBoxInfo talkBoxInfo = new TalkBoxInfo();
            if (Friend.getCode().equals(talkBox.getTalkType())) {
                UsersEntity user = usersDao.selectById(talkBox.getTalkId());
                talkBoxInfo.setUserId(userId);
                talkBoxInfo.setTalkType(Friend.getCode());
                talkBoxInfo.setTalkId(user.getId());
                talkBoxInfo.setTalkName(user.getUsername());
                talkBoxInfo.setTalkAvatar(user.getAvatar());
                talkBoxInfo.setTalkTime(user.getLastLoginTime());
                talkBoxInfo.setOnLine(user.getOnlineStatus());
                talkBoxInfo.setTop(talkBox.getTop());
            } else if (Group.getCode().equals(talkBox.getTalkType())) {
                GroupEntity groups = groupService.queryTalkBoxById(talkBox.getTalkId());
                talkBoxInfo.setUserId(userId);
                talkBoxInfo.setTalkType(Group.getCode());
                talkBoxInfo.setTalkId(groups.getId());
                talkBoxInfo.setTalkName(groups.getGroupName());
                talkBoxInfo.setTalkAvatar(groups.getGroupAvatar());
                talkBoxInfo.setOnLine(-1);
                talkBoxInfo.setTop(talkBox.getTop());
            }
            talkBoxInfoList.add(talkBoxInfo);
        }
        return talkBoxInfoList;
    }

    @Override
    public void addTalkBoxInfo(Long userId, Long talkId, Integer talkType) {
        talkBoxService.addTalkBoxInfo(userId, talkId, talkType);
    }

    @Override
    public List<UserFriendInfo> queryUserFriendInfoList(Long userId, Integer page) {
        List<UserFriendInfo> friendIdList = friendService.queryUserFriendInfoList(userId, pageSize * (page - 1));
        return friendIdList;
    }

    @Override
    public List<GroupInfo> queryUserGroupInfoList(Long userId) { ;
        List<GroupInfo> groupList = groupService.queryUserGroupList(userId);
        return groupList;
    }

    @Override
    public List<LuckUserInfo> queryFuzzyUserInfoList(String account, String searchKey) {
        // 查询当前用户userId
        Long userId = usersDao.selectOne(new QueryWrapper<UsersEntity>().eq("account", account)).getId();
        List<LuckUserInfo> luckUserInfoList = new ArrayList<>();
        List<UsersEntity> userList = usersDao.queryFuzzyUserList(account, searchKey);
        for (UsersEntity user : userList) {
            LuckUserInfo userInfo = new LuckUserInfo(user.getId(), user.getAccount(),
                    user.getUsername(), user.getAvatar(), 0);
            FriendEntity userFriend = friendService.queryUserFriendById(userId, user.getId());
            if (null != userFriend) {
                userInfo.setStatus(2);
            }
            luckUserInfoList.add(userInfo);
        }
        return luckUserInfoList;
    }

    @Override
    public void addUserFriend(List<UserFriend> userFriendList) {
        friendService.addUserFriend(userFriendList);
    }

    @Override
    public void asyncAppendChatRecord(ChatRecordInfo chatRecordInfo) {
        ChatRecordEntity chatRecord = BeanBuilderAssistant.chatInfoToChatEnt(chatRecordInfo);
        chatRecordService.appendChatRecord(chatRecord);
    }

    @Override
    public List<ChatRecordInfo> queryChatRecordInfoList(Long talkId, Long userId, Integer talkType, Integer page) {
        List<ChatRecordInfo> chatRecordInfoList = new ArrayList<>();
        List<ChatRecordEntity> list = new ArrayList<>();
        if (Friend.getCode().equals(talkType)){
            list = chatRecordService.queryUserChatRecordList(talkId, userId, page);
        } else if (Group.getCode().equals(talkType)){
            list =  chatRecordService.queryGroupsChatRecordList(talkId, page);
        }
        for (ChatRecordEntity chatRecord : list) {
            ChatRecordInfo chatRecordInfo = new ChatRecordInfo();
            chatRecordInfo.setUserId(chatRecord.getUserId());
            chatRecordInfo.setFriendId(chatRecord.getFriendId());
            chatRecordInfo.setMsgContent(chatRecord.getMessage());
            chatRecordInfo.setMsgType(chatRecord.getMsgType());
            chatRecordInfo.setTalkTime(chatRecord.getMsgTime());
            chatRecordInfoList.add(chatRecordInfo);
        }
        return chatRecordInfoList;
    }

    @Override
    public void deleteUserTalk(Long talkBoxId) {
        talkBoxService.deleteUserTalk(talkBoxId);
    }

    @Override
    public List<Long> queryUserGroupsIdList(Long userId) {
        return groupService.queryUserGroupsIdList(userId);
    }

    @Override
    public List<Long> queryTalkBoxGroupsIdList(Long userId) {
        return talkBoxService.queryTalkBoxGroupIdList(userId);
    }

    @Override
    public UsersEntity queryUserInfoByAccount(String account) {
        QueryWrapper<UsersEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("account", account);
        queryWrapper.eq("status", StatusEnum.NORMAL_USE.code());
        queryWrapper.eq("is_deleted", DelEnum.NORMAL.code());
        return usersDao.selectOne(queryWrapper);
    }

    @Override
    public List<UserFriendInfo> queryUserFansInfoList(Long userId, Integer page) {
        List<UserFriendInfo> friendIdList = friendService.queryUserFansInfoList(userId, pageSize * (page - 1));
        return friendIdList;
    }

    @Override
    public boolean deleteUserFriendFromFansRelation(Long userId, Long fansId) {
        return friendService.deleteUserFriendFromFansRelation(userId, fansId);
    }

    @Override
    public boolean deleteUserFriendRelation(Long userId, Long friendId) {
        return friendService.deleteUserFriendRelation(userId, friendId);
    }

    @Override
    public List<UserFriendInfo> searchUserFriendInfoList(UserFriendQuery query) {
        List<UserFriendInfo> friendIdList = friendService.
                searchUserFriendInfoList(query);
        return friendIdList;
    }

    @Override
    public List<UserFriendInfo> searchUserFansInfoList(UserFriendQuery query) {
        List<UserFriendInfo> friendIdList = friendService.
                searchUserFansInfoList(query);
        return friendIdList;
    }

    @Override
    public HeaderNavUserInfoVO queryUserHeaderInfo(Long userId) {
        // 1.服务调用作品模块获取信息
        ResultEntity<HeaderNavUserInfoVO> worksRes = worksFeignService.getWorksCountByUserId(userId);
        HeaderNavUserInfoVO target = worksRes.getData();
        return target;
    }

    @Override
    public List<UserDataInfo> getUserIdList() {
        return usersDao.getUserIdList(UserEnum.NORMAL_USE.code(), DelEnum.NORMAL.code());
    }

    @Override
    public UserTO getUserToInfoById(Long userId) {
        UsersEntity usersEntity = usersDao.selectById(userId);
        UserTO target = new UserTO();
        target.setUserId(usersEntity.getId());
        target.setAvatar(usersEntity.getAvatar());
        target.setUsername(usersEntity.getUsername());
        target.setUserPhone(usersEntity.getUserPhone());
        target.setAccount(usersEntity.getAccount());
        target.setLastLoginTime(usersEntity.getLastLoginTime());
        return target;
    }

    @Override
    public NoticeTO addNoticeInfo(NoticeTO notice) {
        return systemFeignService.addNotice(notice).getData();
    }

    @Override
    public SimpleWorksTO getSimpleWorksInfo(Long worksId) {
        return worksFeignService.getWorksSimpleInfo(worksId).getData();
    }

    @Override
    public List<Long> getUserIdFind30() {
        return usersDao.getUserIdFind30(StatusEnum.NORMAL_USE.code(), DelEnum.NORMAL.code());
    }

    @Override
    public List<Long> queryUserFollowIdList(Long userId) {
        return usersDao.queryUserFollowIdList(userId, StatusEnum.NORMAL_USE.code(), DelEnum.NORMAL.code());
    }

    @Override
    public List<Long> queryUserFriendIdList(Long userId) {
        // return usersDao.queryUserFriendIdList(userId, StatusEnum.NORMAL_USE.code(), DelEnum.NORMAL.code());
        return new ArrayList<>();
    }

    @Override
    public UserLoginTO getUserInfoByPhone(String phone) {
        QueryWrapper<UsersEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_phone", phone);
        UsersEntity usersEntity = usersDao.selectOne(queryWrapper);
        UserLoginTO target = new UserLoginTO();
        BeanUtils.copyProperties(usersEntity, target);
        target.setUserId(usersEntity.getId());
        return target;
    }

    @Override
    public UserLoginTO getUserInfoByAccount(String account) {
        QueryWrapper<UsersEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("account", account);
        UsersEntity usersEntity = usersDao.selectOne(queryWrapper);
        UserLoginTO target = new UserLoginTO();
        BeanUtils.copyProperties(usersEntity, target);
        target.setUserId(usersEntity.getId());
        return target;
    }

    @Override
    public UserSimpleTO getUserSimpleInfoById(Long userId, Long friendId) {
        UsersEntity usersEntity = usersDao.selectById(friendId);
        // 调用判断是否已关注
        boolean follow = false;
        if (userId != null) {
            follow = friendService.checkUserFriend(userId, friendId);
        }
        UserSimpleTO target = new UserSimpleTO();
        BeanUtils.copyProperties(usersEntity, target);
        target.setUserId(usersEntity.getId());
        target.setFansNum(usersEntity.getFollowerCount());
        target.setFollow(follow);
        target.setTotalLikeNum(usersEntity.getTotalFavorited());
        return target;
    }

}